Un rapport sur les erreurs de classification des races de chiens a été soumis à l’association de protection des animaux. Dans ce rapport, il est recommandé d’implémenter une solution de détection d’objet pour améliorer la qualité des photos. Cette solution doit isoler l’objet à classifier en procédant à un rognage. Cette nouvelle méthode fera appel au dernier YOLO, version 4.
Ce notebook présente les résultats de classification du modèle Xception entraînés avec les photos rognées.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("default")
import seaborn as sns
from keras.models import load_model
from keras.preprocessing.image import load_img, img_to_array
from sklearn.metrics import classification_report
def get_breed(file):
image = load_img(file, target_size=(299, 299))
input_array = np.reshape(img_to_array(image), (-1, 299, 299, 3)) / 255
# Prédiction de la race
output = model.predict(input_array)
return class_label.at[output.argmax(axis=-1)[0], 'index']
def get_top3_breeds(model, file):
image = load_img(file, target_size=(299, 299))
input_array = np.reshape(img_to_array(image), (-1, 299, 299, 3)) / 255
# Prédiction de la race
output = model.predict(input_array)
df_out = pd.DataFrame(output[0])
top3_breeds = pd.merge(class_label, df_out, left_index=True, right_index=True).rename(columns={0: 'Probabilité', 'index': 'Race prédite'}).sort_values('Probabilité', ascending=False).head(3)
return top3_breeds
def get_true_breed(file):
return file.split('/')[-2]
model = load_model('src/cropped_best_model_Xception_DataAugmentation_120_breeds.hdf5')
class_label = pd.read_csv('src/class_labels.csv')
test_file = pd.read_csv('src/cropped_test_file.csv')
print(f'Nous avons {test_file.shape[0]} images de test')
Nous avons 4116 images de test
test_file.uri = test_file.uri.str.replace('../input/cropped-stanford-dogs-dataset/img_crop', 'src/img_crop')
%time test_file["predicted_breeds"] = test_file.uri.apply(lambda x: get_breed(x))
test_file
Wall time: 27min 37s
| uri | breeds | predicted_breeds | |
|---|---|---|---|
| 0 | src/img_crop/Lhasa/n02098413_1355.jpg | Lhasa | Lhasa |
| 1 | src/img_crop/English_setter/n02100735_3111.jpg | English_setter | English_setter |
| 2 | src/img_crop/komondor/n02105505_1272.jpg | komondor | komondor |
| 3 | src/img_crop/Great_Dane/n02109047_7072.jpg | Great_Dane | Great_Dane |
| 4 | src/img_crop/keeshond/n02112350_7618.jpg | keeshond | keeshond |
| ... | ... | ... | ... |
| 4111 | src/img_crop/komondor/n02105505_1077.jpg | komondor | komondor |
| 4112 | src/img_crop/Scotch_terrier/n02097298_508.jpg | Scotch_terrier | Scotch_terrier |
| 4113 | src/img_crop/cocker_spaniel/n02102318_3545.jpg | cocker_spaniel | cocker_spaniel |
| 4114 | src/img_crop/clumber/n02101556_2604.jpg | clumber | clumber |
| 4115 | src/img_crop/basset/n02088238_12563.jpg | basset | basset |
4116 rows × 3 columns
error_predict = test_file[test_file.breeds != test_file.predicted_breeds]
error_predict.reset_index(drop=True, inplace=True)
error_predict
| uri | breeds | predicted_breeds | |
|---|---|---|---|
| 0 | src/img_crop/Siberian_husky/n02110185_7246.jpg | Siberian_husky | Eskimo_dog |
| 1 | src/img_crop/Siberian_husky/n02110185_2593.jpg | Siberian_husky | Eskimo_dog |
| 2 | src/img_crop/dhole/n02115913_4336.jpg | dhole | dingo |
| 3 | src/img_crop/Lhasa/n02098413_20304.jpg | Lhasa | Shih-Tzu |
| 4 | src/img_crop/Siberian_husky/n02110185_712.jpg | Siberian_husky | Eskimo_dog |
| ... | ... | ... | ... |
| 354 | src/img_crop/Australian_terrier/n02096294_5531... | Australian_terrier | Yorkshire_terrier |
| 355 | src/img_crop/Labrador_retriever/n02099712_221.jpg | Labrador_retriever | Mexican_hairless |
| 356 | src/img_crop/Lakeland_terrier/n02095570_4511.jpg | Lakeland_terrier | soft-coated_wheaten_terrier |
| 357 | src/img_crop/wire-haired_fox_terrier/n02095314... | wire-haired_fox_terrier | Lakeland_terrier |
| 358 | src/img_crop/Appenzeller/n02107908_7205.jpg | Appenzeller | kelpie |
359 rows × 3 columns
i = 1
for img in error_predict.uri.head(20):
print(f"Cas n°{i}")
display(load_img(img))
display("Race indiquée par les données : " + get_true_breed(img))
display(get_top3_breeds(model, img))
print("#############################################################")
print("")
i += 1
Cas n°1
'Race indiquée par les données : Siberian_husky'
| Race prédite | Probabilité | |
|---|---|---|
| 24 | Eskimo_dog | 0.641019 |
| 64 | Siberian_husky | 0.330398 |
| 101 | malamute | 0.007464 |
############################################################# Cas n°2
'Race indiquée par les données : Siberian_husky'
| Race prédite | Probabilité | |
|---|---|---|
| 24 | Eskimo_dog | 0.562865 |
| 64 | Siberian_husky | 0.409635 |
| 101 | malamute | 0.024177 |
############################################################# Cas n°3
'Race indiquée par les données : dhole'
| Race prédite | Probabilité | |
|---|---|---|
| 92 | dingo | 0.530664 |
| 91 | dhole | 0.390960 |
| 52 | Pembroke | 0.021145 |
############################################################# Cas n°4
'Race indiquée par les données : Lhasa'
| Race prédite | Probabilité | |
|---|---|---|
| 63 | Shih-Tzu | 0.569442 |
| 43 | Lhasa | 0.317452 |
| 44 | Maltese_dog | 0.058063 |
############################################################# Cas n°5
'Race indiquée par les données : Siberian_husky'
| Race prédite | Probabilité | |
|---|---|---|
| 24 | Eskimo_dog | 0.710461 |
| 64 | Siberian_husky | 0.268738 |
| 101 | malamute | 0.005718 |
############################################################# Cas n°6
'Race indiquée par les données : Brabancon_griffon'
| Race prédite | Probabilité | |
|---|---|---|
| 82 | boxer | 0.433387 |
| 109 | redbone | 0.122197 |
| 117 | vizsla | 0.117999 |
############################################################# Cas n°7
'Race indiquée par les données : Tibetan_mastiff'
| Race prédite | Probabilité | |
|---|---|---|
| 46 | Newfoundland | 0.902897 |
| 67 | Tibetan_mastiff | 0.087440 |
| 93 | flat-coated_retriever | 0.006488 |
############################################################# Cas n°8
'Race indiquée par les données : American_Staffordshire_terrier'
| Race prédite | Probabilité | |
|---|---|---|
| 65 | Staffordshire_bullterrier | 0.709105 |
| 3 | American_Staffordshire_terrier | 0.285813 |
| 37 | Italian_greyhound | 0.001523 |
############################################################# Cas n°9
'Race indiquée par les données : Eskimo_dog'
| Race prédite | Probabilité | |
|---|---|---|
| 64 | Siberian_husky | 0.538842 |
| 24 | Eskimo_dog | 0.450009 |
| 101 | malamute | 0.006090 |
############################################################# Cas n°10
'Race indiquée par les données : standard_poodle'
| Race prédite | Probabilité | |
|---|---|---|
| 104 | miniature_poodle | 0.433527 |
| 113 | standard_poodle | 0.340419 |
| 115 | toy_poodle | 0.215670 |
############################################################# Cas n°11
'Race indiquée par les données : English_foxhound'
| Race prédite | Probabilité | |
|---|---|---|
| 77 | beagle | 0.484307 |
| 69 | Walker_hound | 0.389105 |
| 20 | English_foxhound | 0.113571 |
############################################################# Cas n°12
'Race indiquée par les données : Lakeland_terrier'
| Race prédite | Probabilité | |
|---|---|---|
| 119 | wire-haired_fox_terrier | 0.733794 |
| 41 | Lakeland_terrier | 0.248038 |
| 116 | toy_terrier | 0.003419 |
############################################################# Cas n°13
'Race indiquée par les données : English_springer'
| Race prédite | Probabilité | |
|---|---|---|
| 88 | cocker_spaniel | 0.672492 |
| 22 | English_springer | 0.231912 |
| 21 | English_setter | 0.070425 |
############################################################# Cas n°14
'Race indiquée par les données : wire-haired_fox_terrier'
| Race prédite | Probabilité | |
|---|---|---|
| 41 | Lakeland_terrier | 0.717008 |
| 119 | wire-haired_fox_terrier | 0.278717 |
| 2 | Airedale | 0.001091 |
############################################################# Cas n°15
'Race indiquée par les données : wire-haired_fox_terrier'
| Race prédite | Probabilité | |
|---|---|---|
| 41 | Lakeland_terrier | 0.523132 |
| 119 | wire-haired_fox_terrier | 0.461295 |
| 106 | otterhound | 0.004807 |
############################################################# Cas n°16
'Race indiquée par les données : Brabancon_griffon'
| Race prédite | Probabilité | |
|---|---|---|
| 51 | Pekinese | 0.975127 |
| 13 | Brabancon_griffon | 0.015836 |
| 53 | Pomeranian | 0.004960 |
############################################################# Cas n°17
'Race indiquée par les données : standard_schnauzer'
| Race prédite | Probabilité | |
|---|---|---|
| 105 | miniature_schnauzer | 0.574383 |
| 114 | standard_schnauzer | 0.424880 |
| 94 | giant_schnauzer | 0.000322 |
############################################################# Cas n°18
'Race indiquée par les données : kelpie'
| Race prédite | Probabilité | |
|---|---|---|
| 54 | Rhodesian_ridgeback | 0.253566 |
| 98 | kelpie | 0.236347 |
| 92 | dingo | 0.146088 |
############################################################# Cas n°19
'Race indiquée par les données : redbone'
| Race prédite | Probabilité | |
|---|---|---|
| 117 | vizsla | 0.518589 |
| 109 | redbone | 0.272700 |
| 54 | Rhodesian_ridgeback | 0.202460 |
############################################################# Cas n°20
'Race indiquée par les données : cocker_spaniel'
| Race prédite | Probabilité | |
|---|---|---|
| 46 | Newfoundland | 0.296324 |
| 89 | collie | 0.102446 |
| 4 | Appenzeller | 0.095293 |
#############################################################
Les erreurs sont désormais dues à des erreurs d'attribution des races, à des photos de jeunes chiens, ou à des races qui se ressemblent fortement.
accuracy_best_model = round((test_file.shape[0] - error_predict.shape[0]) / test_file.shape[0]*100, 1)
print(f'Précision du modèle : {accuracy_best_model} %')
Précision du modèle : 91.3 %
Le modèle entraîné sur les photos rognés donne de meilleurs performance (+4 %). Recommendations :
class_report = classification_report(test_file.breeds, test_file.predicted_breeds, output_dict=True)
class_report_df = pd.DataFrame.from_dict(class_report, orient='columns').transpose().head(-3)
pd.set_option('display.max_rows', None)
class_report_df.sort_values('precision')
| precision | recall | f1-score | support | |
|---|---|---|---|---|
| Eskimo_dog | 0.486486 | 0.642857 | 0.553846 | 28.0 |
| miniature_poodle | 0.666667 | 0.880000 | 0.758621 | 25.0 |
| Border_collie | 0.666667 | 0.965517 | 0.788732 | 29.0 |
| Siberian_husky | 0.689655 | 0.500000 | 0.579710 | 40.0 |
| Lakeland_terrier | 0.718750 | 0.958333 | 0.821429 | 48.0 |
| American_Staffordshire_terrier | 0.724138 | 0.750000 | 0.736842 | 28.0 |
| Norfolk_terrier | 0.729730 | 0.964286 | 0.830769 | 28.0 |
| Irish_wolfhound | 0.739130 | 0.971429 | 0.839506 | 35.0 |
| EntleBucher | 0.750000 | 0.916667 | 0.825000 | 36.0 |
| standard_schnauzer | 0.750000 | 0.777778 | 0.763636 | 27.0 |
| Staffordshire_bullterrier | 0.766667 | 0.920000 | 0.836364 | 25.0 |
| Yorkshire_terrier | 0.787879 | 0.866667 | 0.825397 | 30.0 |
| kuvasz | 0.791667 | 0.863636 | 0.826087 | 22.0 |
| Labrador_retriever | 0.800000 | 0.888889 | 0.842105 | 36.0 |
| vizsla | 0.805556 | 1.000000 | 0.892308 | 29.0 |
| English_foxhound | 0.812500 | 0.812500 | 0.812500 | 32.0 |
| Appenzeller | 0.815789 | 0.756098 | 0.784810 | 41.0 |
| beagle | 0.833333 | 0.975610 | 0.898876 | 41.0 |
| malamute | 0.837838 | 0.837838 | 0.837838 | 37.0 |
| kelpie | 0.840000 | 0.777778 | 0.807692 | 27.0 |
| Newfoundland | 0.844444 | 0.974359 | 0.904762 | 39.0 |
| Walker_hound | 0.846154 | 0.785714 | 0.814815 | 28.0 |
| English_setter | 0.850000 | 0.944444 | 0.894737 | 18.0 |
| cocker_spaniel | 0.850000 | 0.894737 | 0.871795 | 38.0 |
| West_Highland_white_terrier | 0.853659 | 0.972222 | 0.909091 | 36.0 |
| Bouvier_des_Flandres | 0.857143 | 0.960000 | 0.905660 | 25.0 |
| Italian_greyhound | 0.860465 | 0.880952 | 0.870588 | 42.0 |
| miniature_schnauzer | 0.861111 | 0.968750 | 0.911765 | 32.0 |
| toy_terrier | 0.863636 | 0.974359 | 0.915663 | 39.0 |
| Irish_setter | 0.864865 | 1.000000 | 0.927536 | 32.0 |
| otterhound | 0.878788 | 0.906250 | 0.892308 | 32.0 |
| flat-coated_retriever | 0.880000 | 0.956522 | 0.916667 | 23.0 |
| Pembroke | 0.888889 | 0.952381 | 0.919540 | 42.0 |
| soft-coated_wheaten_terrier | 0.891892 | 0.970588 | 0.929577 | 34.0 |
| dingo | 0.891892 | 0.942857 | 0.916667 | 35.0 |
| clumber | 0.897436 | 1.000000 | 0.945946 | 35.0 |
| Rhodesian_ridgeback | 0.900000 | 0.937500 | 0.918367 | 48.0 |
| toy_poodle | 0.900000 | 0.782609 | 0.837209 | 23.0 |
| affenpinscher | 0.903226 | 0.933333 | 0.918033 | 30.0 |
| cairn | 0.904762 | 0.926829 | 0.915663 | 41.0 |
| bloodhound | 0.906250 | 0.935484 | 0.920635 | 31.0 |
| schipperke | 0.906250 | 1.000000 | 0.950820 | 29.0 |
| Dandie_Dinmont | 0.906977 | 0.975000 | 0.939759 | 40.0 |
| Samoyed | 0.911765 | 0.911765 | 0.911765 | 34.0 |
| Saluki | 0.916667 | 1.000000 | 0.956522 | 33.0 |
| silky_terrier | 0.921053 | 0.921053 | 0.921053 | 38.0 |
| Lhasa | 0.921569 | 0.940000 | 0.930693 | 50.0 |
| Scotch_terrier | 0.923077 | 0.888889 | 0.905660 | 27.0 |
| papillon | 0.923077 | 1.000000 | 0.960000 | 36.0 |
| Weimaraner | 0.923077 | 1.000000 | 0.960000 | 24.0 |
| collie | 0.923077 | 0.750000 | 0.827586 | 32.0 |
| golden_retriever | 0.925926 | 0.892857 | 0.909091 | 28.0 |
| Mexican_hairless | 0.925926 | 0.961538 | 0.943396 | 26.0 |
| Maltese_dog | 0.926829 | 0.904762 | 0.915663 | 42.0 |
| German_shepherd | 0.931034 | 0.964286 | 0.947368 | 28.0 |
| dhole | 0.933333 | 0.933333 | 0.933333 | 15.0 |
| basenji | 0.934783 | 0.977273 | 0.955556 | 44.0 |
| Greater_Swiss_Mountain_dog | 0.937500 | 0.810811 | 0.869565 | 37.0 |
| Pekinese | 0.939394 | 0.939394 | 0.939394 | 33.0 |
| boxer | 0.941176 | 0.864865 | 0.901408 | 37.0 |
| standard_poodle | 0.941176 | 0.727273 | 0.820513 | 22.0 |
| Tibetan_terrier | 0.944444 | 0.944444 | 0.944444 | 36.0 |
| whippet | 0.948718 | 0.860465 | 0.902439 | 43.0 |
| English_springer | 0.950000 | 0.863636 | 0.904762 | 22.0 |
| Bernese_mountain_dog | 0.950000 | 0.904762 | 0.926829 | 42.0 |
| Old_English_sheepdog | 0.955556 | 1.000000 | 0.977273 | 43.0 |
| Shih-Tzu | 0.956522 | 0.880000 | 0.916667 | 50.0 |
| redbone | 0.960000 | 0.800000 | 0.872727 | 30.0 |
| briard | 0.961538 | 0.925926 | 0.943396 | 27.0 |
| wire-haired_fox_terrier | 0.962963 | 0.684211 | 0.800000 | 38.0 |
| Cardigan | 0.962963 | 0.812500 | 0.881356 | 32.0 |
| Japanese_spaniel | 0.964286 | 0.931034 | 0.947368 | 29.0 |
| French_bulldog | 0.967742 | 0.967742 | 0.967742 | 31.0 |
| Welsh_springer_spaniel | 0.967742 | 1.000000 | 0.983607 | 30.0 |
| Irish_water_spaniel | 0.967742 | 1.000000 | 0.983607 | 30.0 |
| Brabancon_griffon | 0.967742 | 0.937500 | 0.952381 | 32.0 |
| borzoi | 0.967742 | 0.937500 | 0.952381 | 32.0 |
| Leonberg | 0.968750 | 1.000000 | 0.984127 | 31.0 |
| Saint_Bernard | 0.969697 | 1.000000 | 0.984615 | 32.0 |
| komondor | 0.970588 | 0.942857 | 0.956522 | 35.0 |
| black-and-tan_coonhound | 0.971429 | 0.944444 | 0.957746 | 36.0 |
| miniature_pinscher | 0.971429 | 1.000000 | 0.985507 | 34.0 |
| bull_mastiff | 0.971429 | 0.971429 | 0.971429 | 35.0 |
| Sealyham_terrier | 0.972973 | 0.947368 | 0.960000 | 38.0 |
| Norwegian_elkhound | 0.972973 | 0.972973 | 0.972973 | 37.0 |
| bluetick | 0.973684 | 0.973684 | 0.973684 | 38.0 |
| Doberman | 0.974359 | 1.000000 | 0.987013 | 38.0 |
| Airedale | 0.977778 | 0.880000 | 0.926316 | 50.0 |
| Great_Pyrenees | 0.978261 | 0.865385 | 0.918367 | 52.0 |
| Border_terrier | 1.000000 | 1.000000 | 1.000000 | 41.0 |
| malinois | 1.000000 | 0.928571 | 0.962963 | 28.0 |
| Blenheim_spaniel | 1.000000 | 0.958333 | 0.978723 | 24.0 |
| Chihuahua | 1.000000 | 0.913043 | 0.954545 | 23.0 |
| Chesapeake_Bay_retriever | 1.000000 | 0.857143 | 0.923077 | 35.0 |
| African_hunting_dog | 1.000000 | 1.000000 | 1.000000 | 32.0 |
| Brittany_spaniel | 1.000000 | 0.939394 | 0.968750 | 33.0 |
| Bedlington_terrier | 1.000000 | 0.921053 | 0.958904 | 38.0 |
| Boston_bull | 1.000000 | 1.000000 | 1.000000 | 35.0 |
| Australian_terrier | 1.000000 | 0.897959 | 0.946237 | 49.0 |
| pug | 1.000000 | 0.948718 | 0.973684 | 39.0 |
| Sussex_spaniel | 1.000000 | 0.875000 | 0.933333 | 40.0 |
| giant_schnauzer | 1.000000 | 0.837838 | 0.911765 | 37.0 |
| Gordon_setter | 1.000000 | 0.925000 | 0.961039 | 40.0 |
| Shetland_sheepdog | 1.000000 | 0.846154 | 0.916667 | 26.0 |
| Scottish_deerhound | 1.000000 | 0.734694 | 0.847059 | 49.0 |
| basset | 1.000000 | 0.945946 | 0.972222 | 37.0 |
| Rottweiler | 1.000000 | 0.933333 | 0.965517 | 30.0 |
| Pomeranian | 1.000000 | 0.972973 | 0.986301 | 37.0 |
| Norwich_terrier | 1.000000 | 0.750000 | 0.857143 | 36.0 |
| chow | 1.000000 | 1.000000 | 1.000000 | 37.0 |
| Kerry_blue_terrier | 1.000000 | 0.976744 | 0.988235 | 43.0 |
| curly-coated_retriever | 1.000000 | 0.870968 | 0.931034 | 31.0 |
| Irish_terrier | 1.000000 | 0.900000 | 0.947368 | 40.0 |
| Ibizan_hound | 1.000000 | 1.000000 | 1.000000 | 41.0 |
| Tibetan_mastiff | 1.000000 | 0.756757 | 0.861538 | 37.0 |
| Great_Dane | 1.000000 | 0.939394 | 0.968750 | 33.0 |
| groenendael | 1.000000 | 0.916667 | 0.956522 | 24.0 |
| keeshond | 1.000000 | 1.000000 | 1.000000 | 33.0 |
| German_short-haired_pointer | 1.000000 | 0.967742 | 0.983607 | 31.0 |
| Afghan_hound | 1.000000 | 1.000000 | 1.000000 | 52.0 |